/**
 * Copyright (C) 2009-2012, KingHool.com
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program. If not, see http://www.gnu.org/licenses.
 */
package com.kinghool.smodel;

import java.util.List;
import java.util.Map;

import com.kinghool.smodel.query.Query;

/**
 * 
 * @Author Allen Deng(dengtailin@gmail.com) 
 */
public interface ITreeModel extends IModel {
	/**
	 * check the ITreeModel is the root ITreeModel
	 * a ITreeModel is root only when its parent is null
	 */
	public boolean isRoot();   
	
	/**
	 * get the parent of the ITreeModel
	 */
	public ITreeModel getParent();
	
	/**
	 * set the parent of the ITreeModel
	 */
	public void setParent(ITreeModel parent);
	
	
	/**
	 * get the root of the ITreeModel
	 */
	public ITreeModel getRoot();
	
	/**
	 * add a direct child to the ITreeModel, as the child.getId() for the child name
	 */
	public void addChild(ITreeModel child);
	 
	/**
	 * add a child with propValPairs as properties
	 */
	public ITreeModel addChild(String childFullName, Map<String, ? extends Object> propValPairs); 
	 
	/**
	 * add a blank child
	 */
	public ITreeModel addChild(String childFullName);
	
	/**
	 * remove direct indexed child
	 */
	public void removeChild(int index);
	 
	/**
	 * remove direct child
	 */
	public void removeChild(ITreeModel child); 
	
	/**
	 * remove all the children whose name equals the given childFullName from the ITreeModel
	 */
	public void removeTreeChild(String childFullName, Query... queries);
	
	/**
	 * remove the indexed child whose name equals the given childFullName from the ITreeModel
	 */
	public void removeTreeChild(String childFullName, int index);

	/**
	 * remove the given child whose name equals the given childFullName from the ITreeModel
	 */
	public void removeTreeChild(String childFullName, ITreeModel child);
	
	/**
	 * get the direct child names of the ITreeModel
	 */
	public List<String> getChildNames();
	
	/**
	 * get all direct children
	 */
	public Map<String, List<ITreeModel>> getAllChildren();
	
	/**
	 * move the direct child(targetIndex) to the sourceIndex in the child list
	 */
	public void moveChild(int sourceIndex, int targetIndex);
	 
	/**
	 * move the direct child(target) to the location where child(source) located in the child list
	 */
	public void moveChild(ITreeModel source, ITreeModel target);
	
	/**
	 * move the child(targetIndex) named childFullName to the sourceIndex in the child list
	 */
	public void moveTreeChild(String childFullName, int sourceIndex, int targetIndex);
	
	/**
	 * move the child(target) named childFullName  to the location where child(source) located in the child list
	 */
	public void moveTreeChild(String childFullName, ITreeModel source, ITreeModel target);
	
	/**
	 * check the child defined
	 */
	public boolean isTreeChild(String childFullName);
	
	/**
	 * check the child exists in child list
	 */
	public boolean hasTreeChild(String childFullName, Query... queries);

	/**
	 * get all the direct children of the ITreeModel
	 */
	public List<ITreeModel> getChild(Query... queries);
	
	/**
	 * get the indexed the direct children of the ITreeModel
	 */
	public ITreeModel getChild(int index, Query... queries);
	
	/**
	 * get all the children whose name is childFullName of the ITreeModel
	 */
	public List<ITreeModel> getTreeChild(String childFullName, Query... queries);
	
	/**
	 * get the first child whose name is childFullName of the ITreeModel
	 */
	public ITreeModel getFirstTreeChild(String childFullName, Query... queries);
	
	/**
	 * get the indexed child whose name is childFullName of the ITreeModel
	 */
	public ITreeModel getTreeChild(String childFullName, int index, Query... queries);
	
	/**
	 * get TreeChild by queryStr
	 * ChildName{attr1=attr1Value, attr2=attr2Value}[0]/SubChildName[1]
	 */
	public ITreeModel queryFirstTreeChild(String queryStr);
	
	/**
	 * get TreeChild by queryStr
	 * ChildName{attr1=attr1Value, attr2=attr2Value}[0]/SubChildName
	 */
	public List<ITreeModel> queryTreeChild(String queryStr);
	
	/**
	 * clarify the ITreeModel, remove the blank ITreeModel(no child, no property ITreeModel which is not mandatory)
	 */
	public void clarify();
	
	/**
	 * check the ITreeModel has children exist
	 */
	public boolean hasChildren();
	
	/**
	 * clone
	 */
	public ITreeModel clone() throws CloneNotSupportedException;
}
